#include "Frustum.h"
#include <math.h>
#define ANG2RAD 3.14159265358979323846/180.0

namespace lib3dw
{
	Frustum::Frustum()
	{
		nearD = 0.0;
		farD = 0.0;
		ratio = 0.0;
		angle = 0.0;
		tang = 0.0;
		nw = 0.0;
		nh = 0.0;
		fw = 0.0;
		fh = 0.0;
	}

	Frustum::~Frustum()
	{
	}

	void Frustum::SetViewport(float newAngle, float newRatio, float newNearD, float newFarD)
	{
		angle = newAngle;
		ratio = newRatio;
		nearD = newNearD;
		farD = newFarD;

		tang = (float)tan(angle* ANG2RAD * 0.5) ;
		nh = nearD * tang;
		nw = nh * ratio; 
		fh = farD  * tang;
		fw = fh * ratio;
	}


	void Frustum::SetCamera(Vector3 &p, Vector3 &l, Vector3 &u)
	{
		Vector3 dir, nc, fc, X, Y, Z;

		Z = p - l;
		Z.normalize();
		X = cross(u, Z);
		X.normalize();
		Y = cross(Z, X);

		nc = p - Z * nearD;
		fc = p - Z * farD;

		Vector3  Xnw = X * nw;
		Vector3  Xfw = X * fw;
		Vector3  Ynh = Y * nh;
		Vector3  Yfh = Y * fh;
		
		ntl = nc + Ynh - Xnw;
		ntr = nc + Ynh + Xnw;
		nbl = nc - Ynh - Xnw;
		nbr = nc - Ynh + Xnw;

		ftl = fc + Yfh - Xfw;
		ftr = fc + Yfh + Xfw;
		fbl = fc - Yfh - Xfw;
		fbr = fc - Yfh + Xfw;

		pl[TOP].set3Points(ntr,ntl,ftl);
		pl[BOTTOM].set3Points(nbl,nbr,fbr);
		pl[LEFT].set3Points(ntl,nbl,fbl);
		pl[RIGHT].set3Points(nbr,ntr,fbr);
		pl[NEARP].set3Points(ntl,ntr,nbr);
		pl[FARP].set3Points(ftr,ftl,fbl);
	}

	int Frustum::Test(Box* b)
	{
		int result = INSIDE;
		for(int i=0; i < 6; i++) 
		{
			if (pl[i].distance(b->parameters[0]) < 0)
			{
				return OUTSIDE;
			}
			else if (pl[i].distance(b->parameters[1]) < 0)
			{
				result =  INTERSECT;
			}
		}
		return(result);
	 }
}